using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
namespace Microsoft.Phone.Controls.Maps.Core
{
	internal class PinchStretchHandler
	{
		private bool inProgress;
		private Point[] lastKnownPoints = new Point[2];
		private ushort minimumUpdateThreshold = 3;
		private Point[] trackingPoints = new Point[2];
		private UIElement root;
		private bool isEnabled;
		public event EventHandler<PinchStretchEventArgs> PinchStretchReported
		{
			[MethodImpl(32)]
			add
			{
				this.PinchStretchReported = (EventHandler<PinchStretchEventArgs>)Delegate.Combine(this.PinchStretchReported, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.PinchStretchReported = (EventHandler<PinchStretchEventArgs>)Delegate.Remove(this.PinchStretchReported, value);
			}
		}
		public PinchStretchHandler(UIElement element)
		{
			if (element == null)
			{
				throw new ArgumentNullException("element");
			}
			this.root = element;
		}
		public void Enable(bool enable)
		{
			if (enable && !this.isEnabled)
			{
				UIElement arg_5C_0 = this.root;
				TouchHandlers touchHandlers = new TouchHandlers();
				touchHandlers.TouchDown = delegate(object sender, TouchEventArgs e)
				{
					e.TouchPoint.get_TouchDevice().Capture(this.root);
				};
				touchHandlers.CapturedTouchUp = delegate(object sender, TouchEventArgs e)
				{
					this.Reset();
				};
				touchHandlers.CapturedTouchReported = new EventHandler<TouchReportedEventArgs>(this.OnCapturedTouchReported);
				TouchHelper.AddHandlers(arg_5C_0, touchHandlers);
				this.isEnabled = true;
				return;
			}
			if (!enable && this.isEnabled)
			{
				TouchHelper.RemoveHandlers(this.root);
				this.isEnabled = false;
			}
		}
		private void Reset()
		{
			this.inProgress = false;
			this.trackingPoints = new Point[2];
			this.lastKnownPoints = new Point[2];
		}
		private void OnCapturedTouchReported(object sender, TouchReportedEventArgs e)
		{
			if (Enumerable.Count<Point>(e.TouchPoints) == 2)
			{
				this.RecordPoints(Enumerable.ElementAt<Point>(e.TouchPoints, 0), Enumerable.ElementAt<Point>(e.TouchPoints, 1));
				this.inProgress = true;
			}
		}
		private void RecordPoints(Point p1, Point p2)
		{
			this.trackingPoints[0] = p1;
			this.trackingPoints[1] = p2;
			if (!this.inProgress)
			{
				this.lastKnownPoints[0] = p1;
				this.lastKnownPoints[1] = p2;
			}
			Point point = PhysicsHelper.Delta(this.trackingPoints[0], this.lastKnownPoints[0]);
			Point point2 = PhysicsHelper.Delta(this.trackingPoints[1], this.lastKnownPoints[1]);
			if (!this.inProgress || PhysicsHelper.ExceedsThreshold(point, (long)((ulong)this.minimumUpdateThreshold)) || PhysicsHelper.ExceedsThreshold(point2, (long)((ulong)this.minimumUpdateThreshold)))
			{
				PinchStretchData data = new PinchStretchData
				{
					ContactPoint1 = this.trackingPoints[0],
					ContactPoint2 = this.trackingPoints[1],
					ContactPoint1Delta = point,
					ContactPoint2Delta = point2
				};
				Point p3 = PhysicsHelper.Center(this.lastKnownPoints[0], this.lastKnownPoints[1]);
				Point point3 = PhysicsHelper.Center(this.trackingPoints[0], this.trackingPoints[1]);
				data.CenterPoint = point3;
				data.CenterPointDelta = PhysicsHelper.Delta(point3, p3);
				double num = PhysicsHelper.Distance(this.lastKnownPoints[0], this.lastKnownPoints[1]);
				double num2 = PhysicsHelper.Distance(this.trackingPoints[0], this.trackingPoints[1]);
				data.Scale = num2 / num;
				this.lastKnownPoints[0] = this.trackingPoints[0];
				this.lastKnownPoints[1] = this.trackingPoints[1];
				this.FirePinchStretchReported(data);
			}
		}
		private void FirePinchStretchReported(PinchStretchData data)
		{
			EventHandler<PinchStretchEventArgs> pinchStretchReported = this.PinchStretchReported;
			if (pinchStretchReported != null)
			{
				pinchStretchReported.Invoke(this, new PinchStretchEventArgs(data));
			}
		}
	}
}
